#include <iostream>
#include <vector>
#include <error.h>
#include <unistd.h>
#include <fcntl.h>
#include <strings.h>
#include<netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
#define BUFSIZE 1024
#define MAXFD  1024
int main(int argc, char*argv[])
{
    int on = 1;
    int backlog = 10;
    int fdbuf[MAXFD] = {-1,};
    int socketId = socket(AF_INET, SOCK_STREAM, 0);
    int flag = fcntl(socketId, F_GETFL, 0);
    fcntl(socketId, F_SETFD, flag|O_NONBLOCK); //将文件描述符设置成非阻塞状态
    if (socketId < 0) {
        cerr << "Error creating socket" << endl;
        return -1;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = inet_addr("192.168.203.133");
    bzero(&addr, sizeof(struct sockaddr_in));
    setsockopt(socketId, SOL_SOCKET, SO_REUSEADDR, (const void *)&on,sizeof(int));
    bind(socketId,(struct sockaddr *)&addr, sizeof(addr));
    int retNum = listen(socketId, backlog);
    if (retNum == -1) {
        printf("retNum = %d\n",retNum);
        exit(-1);
    }

    int clifd = -1; 
    int maxfd = socketId;
    char buf[BUFSIZE];
    fd_set fdsets;
    int acceptBuf[MAXFD] = {};
    struct sockaddr_in cliaddr;
    socklen_t len = sizeof(struct sockaddr_in);
    for(;;) {
        FD_ZERO(&fdsets);
        FD_SET(socketId, &fdsets); //将socketfd加入到sets集合里面
        for (int i = 0; i < MAXFD; i++) {  
            if (acceptBuf[i] != 0) {
                printf("running 111 acceptBuf[i]:%d\n", acceptBuf[i]);
                if (acceptBuf[i] > maxfd) {
                    maxfd = acceptBuf[i];
                } 

                FD_SET(acceptBuf[i], &fdsets);
            }
        }

        //将socketfd加入到相应的集合中
        int events = select(maxfd+1, &fdsets,NULL,NULL,NULL); //将eventfd加入到集合中
        printf("accept eventfd: %d\n",events);
        if (events == -1) {
            cout << "select error" << endl;
            exit(-1);
        }else if (events == 0) {
            cout << "select timeout" << endl;
            continue;
        } else {
            //此时如果FD_ISSET_ERROR
            int cursor = -1;
            printf("select cliend %d\n",clifd);
            if (FD_ISSET(socketId, &fdsets)) {
                printf("running 222\n");  
                for (int i = 0; i < MAXFD; i++)
                {
                    if (acceptBuf[i] == 0)
                    {
                        cursor = i;
                        break;
                    }
                }

                clifd = accept(socketId, (struct sockaddr *)&cliaddr, &len);
                int flag = fcntl(clifd, F_GETFL, 0);
                fcntl(clifd, F_SETFD, flag|O_NONBLOCK); //将文件描述符设置成非阻塞状态
                
                if (cursor == -1) {
                    acceptBuf[cursor] = clifd;
                }

            }

            for(int i = 0; i < MAXFD; i++)
            {
                if (acceptBuf[i] != 0 && FD_ISSET(acceptBuf[i], &fdsets))
                {
                    int retNum = recv(acceptBuf[i], buf, BUFSIZE, 0);
                    printf("running 333:%d%s\n", retNum, buf);
                    if (retNum <= 0) {
                        close(acceptBuf[i]);
                        break;
                    } 
                    printf("accept %s\n", acceptBuf);
                    send(clifd, buf, BUFSIZE, 0);
                }
            }
        }
    }
    return 0;
}